<?php

$image = new Image();
// echo $image->water('Desert.jpg', 'baidu.gif', 0);
$image->suofang('Desert.jpg', '400', '400');

/**
 * 图片处理类
 */
class Image
{

	protected $isRandName; //是否启用随机名
	protected $type; //生成的图片类型
	protected $path; //生成图片保存路径

	function __construct($isRandName = true, $type = 'png', $path = './')
	{
		$this->isRandName = $isRandName;
		$this->type = $type;
		$this->path = $path;
	}

	// 添加水印
	public function water($image, $water, $position, $tmd = 100, $prefix = 'water_')
	{
		// 1.判断图片是否存在
		if(!file_exists($image) || !file_exists($water)){
			die("图片资源不存在");
		}
		// 2.获取图片的宽度和高度
		$imageInfo = self::getImageInfo($image);
		$waterInfo = self::getImageInfo($water);
		// 3.判断水印是否可以贴上去
		if(!$this->checkImg($imageInfo, $waterInfo)){
			exit("水印图片太大");
		}
		// 4.打开图片
		$imageRes = self::openAnyImage($image);
		$waterRes = self::openAnyImage($water);
		// 5.根据图片的位置计算图片的坐标
		$pos = $this->getPosition($position, $imageInfo, $waterInfo);
		// 6.将图片贴过来
		// imagecopymerge(dst_im, src_im, dst_x, dst_y, src_x, src_y, src_w, src_h, pct)
		imagecopymerge($imageRes, $waterRes, $pos['x'], $pos['y'], 0, 0, $waterInfo['width'], $waterInfo['height'], $tmd);
		// 7.得到要保存的图片名
		$newName = $this->createNewName($image, $prefix);
		// 8.得到保存图片的路径，也就是文件的全路径
		$newPath = rtrim($this->path, '/').'/'.$newName;
		// 9.保存图片
		$this->saveImage($imageRes, $newPath);
		// 10.销毁图片资源
		imagedestroy($imageRes);
		imagedestroy($waterRes);

		return $newPath;
	}

	// 缩放方法
	public function suofang($image, $width, $height, $prefix = 'sf_')
	{
		// 1.得到图片原来的宽度和高度
		$info = self::getImageInfo($image);
		// 2.根据图片原来的宽高和最终要缩放框计算得到图像不变形的宽高
		$size = $this->getNewSize($width, $height, $info);
		// 3.打开图片资源
		$imageRes = self::openAnyImage($image);
		// 4.进行缩放
		$newImg = $this->kidOfImage($imageRes, $size, $info);
		// 5.保存图像
		$newName = $this->createNewName($image, $prefix);
		$newPath = rtrim($this->path, '/').'/'.$newName;
		$this->saveImage($newImg, $newPath);
		// 6.销毁图像资源
		imagedestroy($imageRes);
		imagedestroy($newImg);
	}

	// 处理透明色函数
	protected function kidOfImage($srcImg, $size, $imgInfo)
	{
		// 传入新的尺寸，创建一个指定尺寸的图片
		$newImg = imagecreatetruecolor($size['old_w'], $size['old_h']);
		// 定义透明色
		$otsc = imagecolortransparent($srcImg);
		if($otsc >= 0){
			// 取得透明色
			$transparentcolor = imagecolorsforindex($srcImg, $otsc);
			// 创建透明色
			$newtransparentcolor = imagecolorallocate(
				$newImg, 
				$transparentcolor['red'], 
				$transparentcolor['green'], 
				$transparentcolor['blue']
			);
		}else{
			// 将黑色作为透明色，因为创建图像后再第一次分配颜色是背景默认为黑色
			$newtransparentcolor = imagecolorallocate($newImg, 0, 0, 0);
		}
		// 背景色填充透明
		imagefill($newImg, 0, 0, $newtransparentcolor);
		imagecolortransparent($newImg, $newtransparentcolor);

		imagecopyresampled($newImg, $srcImg, $size['x'], $size['y'], 0, 0, $size['new_w'], $size['new_h'], $imgInfo['width'], $imgInfo['height']);
		return $newImg;
	}

	// 计算图像最终宽度和高度
	// $width 最终缩放的宽度 $height 最终缩放的高度 $imgInfo 原始图片的宽度和高度
	protected function getNewSize($width, $height, $imgInfo)
	{
		$size['old_w'] = $width;
		$size['old_h'] = $height;

		$scaleWidth = $width / $imgInfo['width'];
		$scaleHeight = $height / $imgInfo['height'];
		$scaleFinal = min($scaleWidth, $scaleHeight);

		$size['new_w'] = round($imgInfo['width'] * $scaleFinal);
		$size['new_h'] = round($imgInfo['height'] * $scaleFinal);
		if($scaleWidth < $scaleHeight){
			$size['x'] = 0;
			$size['y'] = round(abs($size['new_h'] - $height) / 2);
		}else{
			$size['y'] = 0;
			$size['x'] = round(abs($size['new_w'] - $width) / 2);
		}
		return $size;
	}

	protected function saveImage($imageRes, $newPath)
	{
		// imagepng imagegif imagewbmp
		$func = 'image'.$this->type;
		// 通过变量函数进行保存(函数名是一个变量)
		$func($imageRes, $newPath);
	}
	// 得到文件名
	protected function createNewName($image, $prefix)
	{
		if($this->isRandName){
			$name = $prefix.uniqid().'.'.$this->type;
		}else{
			$name = $prefix.pathinfo($image)['filename'].'.'.$this->type;
		}
		return $name;
	}

	// 计算水印位置
	protected function getPosition($position, $imageInfo, $waterInfo)
	{
		switch ($position) {
			case 1:
				$x = 0;
				$y = 0;
				break;
			case 2:
				$x = ($imageInfo['width'] - $waterInfo['width']) / 2;
				$y = 0;
				break;
			case 3:
				$x = $imageInfo['width'] - $waterInfo['width'];
				$y = 0;
				break;
			case 4:
				$x = 0;
				$y = ($imageInfo['height'] - $waterInfo['height']) / 2;
				break;
			case 5:
				$x = ($imageInfo['width'] - $waterInfo['width']) / 2;
				$y = ($imageInfo['height'] - $waterInfo['height']) / 2;
				break;
			case 6:
				$x = $imageInfo['width'] - $waterInfo['width'];
				$y = ($imageInfo['height'] - $waterInfo['height']) / 2;
				break;
			case 7:
				$x = 0;
				$y = $imageInfo['height'] - $waterInfo['height'];
				break;
			case 8:
				$x = ($imageInfo['width'] - $waterInfo['width']) / 2;
				$y = $imageInfo['height'] - $waterInfo['height'];
				break;
			case 9:
				$x = $imageInfo['width'] - $waterInfo['width'];
				$y = $imageInfo['height'] - $waterInfo['height'];
				break;
			case 0:
				$x = mt_rand(0, $imageInfo['width'] - $waterInfo['width']);
				$y = mt_rand(0, $imageInfo['height'] - $waterInfo['height']);
				break;
		}
		return ['x' => $x, 'y' => $y];
	}

	protected function checkImg($imageInfo, $waterInfo)
	{
		if($imageInfo['height']>$waterInfo['height'] && $imageInfo['width'] > $waterInfo['width']){
			return true;
		}else{
			return false;
		}
	}
	// 获取图片的宽度和高度和mime类型
	static function getImageInfo($image)
	{
		$imageInfo = getimagesize($image);
		$data['width'] = $imageInfo[0];
		$data['height'] = $imageInfo[1];
		$data['mime'] = $imageInfo['mime'];
		return $data;
	}

	// 打开图片
	static function openAnyImage($image)
	{
		$mime = getimagesize($image)['mime'];
		switch ($mime) {
			case 'image/png':
				$img = imagecreatefrompng($image);
				break;
			case 'image/gif':
				$img = imagecreatefromgif($image);
				break;
			case 'image/jpeg':
				$img = imagecreatefromjpeg($image);
				break;
			case 'image/wbmp':
				$img = imagecreatefromwbmp($image);
				break;
			default:
				die('不符合类型');
				break;
		}

		return $img;
	}
}